package com.shenmazong.es.controller;

import com.shenmazong.es.pojo.TbHero;
import com.shenmazong.utils.IdWorker;
import com.shenmazong.utils.ResultResponse;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.query.HighlightQueryBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author 军哥
 * @version 1.0
 * @description: TODO
 * @date 2022/6/27 16:26
 */


@RestController
@Slf4j
@RequestMapping(value = "/es")
public class SearchController {

    @Autowired
    ElasticsearchRestTemplate elasticsearchRestTemplate;

    private Long _id = 0L;

    @PostMapping(value = "/createIndex")
    public ResultResponse createIndex() {
        IndexOperations index = elasticsearchRestTemplate.indexOps(TbHero.class);

        if(!index.exists()) {
            // 创建索引
            index.create();

            // 创建映射
            Document mapping = index.createMapping();
            index.putMapping(mapping);
        }

        return ResultResponse.SUCCESS();
    }

    @PostMapping(value = "/deleteIndex")
    public ResultResponse deleteIndex() {
        IndexOperations index = elasticsearchRestTemplate.indexOps(TbHero.class);
        if(index.exists()) {
            index.delete();
        }

        return ResultResponse.SUCCESS();
    }


    @PostMapping(value = "/add")
    public ResultResponse add(@RequestParam("name") String name, @RequestParam("age") Integer age, @RequestParam("skills") String skills) {
        TbHero tbHero = new TbHero();
        _id = IdWorker.getId();
        tbHero.setId(_id);
        tbHero.setName(name);
        tbHero.setAge(age);
        tbHero.setSkills(skills);

        elasticsearchRestTemplate.save(tbHero);

        return ResultResponse.SUCCESS();
    }

    @PostMapping(value = "/delete")
    public ResultResponse delete() {
        elasticsearchRestTemplate.delete(""+_id, TbHero.class);

        return ResultResponse.SUCCESS();
    }

    @PostMapping(value = "/update")
    public ResultResponse update() {

        TbHero tbHero = elasticsearchRestTemplate.get("" + _id, TbHero.class);
        tbHero.setAge(66);

        elasticsearchRestTemplate.save(tbHero);

        return ResultResponse.SUCCESS();
    }

    @PostMapping(value = "/get")
    public ResultResponse get() {
        TbHero tbHero = elasticsearchRestTemplate.get("" + _id, TbHero.class);

        return ResultResponse.SUCCESS(tbHero);
    }

    @PostMapping(value = "/term")
    public ResultResponse term(
            @RequestParam("keyWord") String keyWord,
            @RequestParam("pageNum") Integer pageNum,
            @RequestParam("pageSize") Integer pageSize
            ) {

        //--1 构造分页
        if(pageNum > 0) {
            pageNum = pageNum -1;
        }
        PageRequest pageRequest = PageRequest.of(pageNum, pageSize);

        //--2 builder
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();

        //--3 构造查询
        NativeSearchQuery query = builder.withPageable(pageRequest)
                .withQuery(QueryBuilders.termQuery("name", keyWord))
                .build();

        //--4 执行查询
        long count = elasticsearchRestTemplate.count(query, TbHero.class);
        SearchHits<TbHero> searchHits = elasticsearchRestTemplate.search(query, TbHero.class);

        //--5 获取查询的结果
        List<SearchHit<TbHero>> hitsSearchHits = searchHits.getSearchHits();
        hitsSearchHits.forEach(item -> {
            TbHero tbHero = item.getContent();
            System.out.println(tbHero);
        });

        //--6 手动分页
        ArrayList<TbHero> tbHeroes = new ArrayList<>();
        hitsSearchHits.forEach(item -> {
            TbHero tbHero = item.getContent();
            tbHeroes.add(tbHero);
        });

        HashMap<String, Object> map = new HashMap<>();
        map.put("records", tbHeroes);
        map.put("pageNum", pageNum+1);
        map.put("pageSize", pageSize);
        map.put("count", count);

        return ResultResponse.SUCCESS(map);
    }

    @PostMapping(value = "/match")
    public ResultResponse match(
            @RequestParam("keyWord") String keyWord,
            @RequestParam("pageNum") Integer pageNum,
            @RequestParam("pageSize") Integer pageSize
    ) {

        //--1 构造分页
        if(pageNum > 0) {
            pageNum = pageNum -1;
        }
        PageRequest pageRequest = PageRequest.of(pageNum, pageSize);

        //--2 builder
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();

        //--3 构造查询
        NativeSearchQuery query = builder.withPageable(pageRequest)
                .withQuery(QueryBuilders.matchQuery("name", keyWord))
                .build();

        //--4 执行查询
        long count = elasticsearchRestTemplate.count(query, TbHero.class);
        SearchHits<TbHero> searchHits = elasticsearchRestTemplate.search(query, TbHero.class);

        //--5 获取查询的结果
        List<SearchHit<TbHero>> hitsSearchHits = searchHits.getSearchHits();
        hitsSearchHits.forEach(item -> {
            TbHero tbHero = item.getContent();
            System.out.println(tbHero);
        });

        //--6 手动分页
        ArrayList<TbHero> tbHeroes = new ArrayList<>();
        hitsSearchHits.forEach(item -> {
            TbHero tbHero = item.getContent();
            tbHeroes.add(tbHero);
        });

        HashMap<String, Object> map = new HashMap<>();
        map.put("records", tbHeroes);
        map.put("pageNum", pageNum+1);
        map.put("pageSize", pageSize);
        map.put("count", count);

        return ResultResponse.SUCCESS(map);
    }

    @PostMapping(value = "/highlight")
    public ResultResponse highlight(
            @RequestParam("keyWord") String keyWord,
            @RequestParam("pageNum") Integer pageNum,
            @RequestParam("pageSize") Integer pageSize
    ) {

        //--1 构造分页
        if(pageNum > 0) {
            pageNum = pageNum -1;
        }
        PageRequest pageRequest = PageRequest.of(pageNum, pageSize);

        //--2 builder
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font color='red>").postTags("</font>").field("name");

        //-- 排序
        FieldSortBuilder order = new FieldSortBuilder("ceateTime").order(SortOrder.DESC);

        //-- 价格区间
        RangeQueryBuilder bookPrice = QueryBuilders.rangeQuery("bookPrice").gte(10.00f).lte(20.00);

        //--3 构造查询
        NativeSearchQuery query = builder.withPageable(pageRequest)
                .withQuery(QueryBuilders.matchQuery("name", keyWord))
                .withQuery(bookPrice)
                .withHighlightBuilder(highlightBuilder)
                .withSort(order)
                .build();

        //--4 执行查询
        long count = elasticsearchRestTemplate.count(query, TbHero.class);
        SearchHits<TbHero> searchHits = elasticsearchRestTemplate.search(query, TbHero.class);

        //--5 获取查询的结果
        List<SearchHit<TbHero>> hitsSearchHits = searchHits.getSearchHits();
        hitsSearchHits.forEach(item -> {
            TbHero tbHero = item.getContent();
            System.out.println(tbHero);
        });

        //--6 手动分页
        ArrayList<TbHero> tbHeroes = new ArrayList<>();
        hitsSearchHits.forEach(item -> {
            TbHero tbHero = item.getContent();

            List<String> names = item.getHighlightField("name");
            if(names != null && names.size()>0) {
                String s = names.get(0);
                tbHero.setName(s);
            }

            tbHeroes.add(tbHero);
        });

        HashMap<String, Object> map = new HashMap<>();
        map.put("records", tbHeroes);
        map.put("pageNum", pageNum+1);
        map.put("pageSize", pageSize);
        map.put("count", count);

        return ResultResponse.SUCCESS(map);
    }
}
